﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using POSSystem.DAL;
using MyGeneration.dOOdads;

namespace POSSystem.BLL
{
    public class Invoices : _Invoices, IPayment
    {
        public enum InvoiceCategories
        {
            Sale = 1,
            Contract,
            Repair,
            Refund,
            BusinessCard
        }

        public static bool IsInvoiceNoExisted(String number)
        {
            try
            {
                Invoices ivc = new Invoices();
                ivc.Where.InvoiceNo.Value = number;
                ivc.Query.Load();

                return ivc.RowCount > 0;
            }
            catch (Exception ex)
            {
                ErrorLog.WriteToFile("Invoices.cs", "IsInvoiceNoExisted", ex.StackTrace);
                throw new Exception("Invoices.IsInvoiceNoExisted(): " + ex.Message);
            }
        }

        public static Invoices GetInvoiceByInvoiceNo(String number)
        {
            try
            {
                Invoices ivc = new Invoices();
                ivc.Where.InvoiceNo.Value = number;
                ivc.Where.Deleted.Value = false;
                ivc.Query.Load();

                return ivc;
            }
            catch (Exception ex)
            {
                ErrorLog.WriteToFile("Invoices.cs", "GetInvoiceByInvoiceNo", ex.StackTrace);
                throw new Exception("Invoices.GetInvoiceByInvoiceNo(): " + ex.Message);
            }
        }

        #region IPayment Members

        public void Pay(decimal amt,  int paymentMethoidID, int userID)
        {
            if (amt <= 0)
                return;
            this.PaidAmount += amt;
            this.LastModifiedByUser = userID;
            this.LastModifiedDate = DateTime.UtcNow.AddHours(SystemVariables.SysVars.TimeZone);
            //InvoicePaymentHistories.AddPaymentHistory(ID, paymentMethoidID, amt, DateTime.Now, userID);
        }

        public void PayFull(int paymentMethoidID, int userID)
        {
            decimal amt = TotalAmount - PaidAmount;
            if (amt <= 0)
                return;
            this.PaidAmount = this.TotalAmount;
            this.LastModifiedByUser = userID;
            this.LastModifiedDate = DateTime.UtcNow.AddHours(SystemVariables.SysVars.TimeZone);
            //InvoicePaymentHistories.AddPaymentHistory(ID, paymentMethoidID, amt , DateTime.Now, userID);
        }

        #endregion

        public static Invoices GetInvoiceByIDs(string ids)
        {
            try
            {
                Invoices v = new Invoices();
                v.Where.ID.Value = ids;
                v.Where.ID.Operator = MyGeneration.dOOdads.WhereParameter.Operand.In;

                v.Query.Load();

                return v;
            }
            catch (Exception ex)
            {
                ErrorLog.WriteToFile("PurchaseOrders.cs", "GetInvoiceByIDs", ex.StackTrace);
                throw new Exception("PurchaseOrders.GetInvoiceByIDs(): " + ex.Message);
            }
        }

        public static void RevertInvoice(int ivcID, int userID)
        {

            TransactionMgr tx = TransactionMgr.ThreadTransactionMgr();

            try
            {
                tx.BeginTransaction();

                Invoices ivc = new Invoices();
                ivc.LoadByPrimaryKey(ivcID);

                if (ivc.RowCount > 0 && ivc.Deleted == false)
                {
                    InvoicePaymentHistories payment = InvoicePaymentHistories.LoadPaymentByInvoiceID(ivcID);
                    decimal paidAmount = 0;
                    if (payment.RowCount > 0)
                    {
                        do
                        {
                            paidAmount += payment.PaidAmount;

                            payment.Deleted = true;
                            payment.LastModifiedByUser = userID;
                            payment.LastModifiedDate = DateTime.UtcNow.AddHours(SystemVariables.SysVars.TimeZone);


                        } while (payment.MoveNext());
                    }

                    if (ivc.s_VoucherID != "" && ivc.s_SpecialDiscount != "")
                    {
                        Vouchers vou = new Vouchers();
                        vou.LoadByPrimaryKey(ivc.VoucherID);
                        if (vou.RowCount > 0)
                        {
                            VoucherSeries vs = new VoucherSeries();
                            vs.LoadByPrimaryKey(vou.SerieID);

                            if (vs.MultiCheckOut && vou.s_Balance != "")
                            {
                                vou.Balance += ivc.SpecialDiscount;
                            }
                            else if (!vs.MultiCheckOut)
                                vou.IsUsed = false;

                            vou.Save();
                        }
                    }

                    InvoiceDetails ivcDetails = InvoiceDetails.GetInvoiceDetails(ivcID);
                    if (ivcDetails.RowCount > 0)
                    {
                        do
                        {
                            if (!ivcDetails.IsColumnNull(InvoiceDetails.ColumnNames.ProductID))
                            {
                                if (ivcDetails.IsColumnNull(InvoiceDetails.ColumnNames.IMEI))
                                {
                                    Products.UpdateProductQty(ivcDetails.ProductID, ivcDetails.Quantity);
                                }
                                else
                                {
                                    ProductDetails d = ProductDetails.GetProductDetailByIMEIs(ivcDetails.s_IMEI);
                                    if (d.RowCount > 0)
                                    {
                                        d.ProductStatusID = (int)ProductDetails.ProductStatus.Purchased;
                                        d.Save();
                                    }
                                    Products.SyncProductQty(ivcDetails.ProductID);
                                }
                            }

                            ivcDetails.Deleted = true;
                            ivcDetails.LastModifiedByUser = userID;
                            ivcDetails.LastModifiedDate = DateTime.UtcNow.AddHours(SystemVariables.SysVars.TimeZone);


                        } while (ivcDetails.MoveNext());
                    }

                    if (!ivc.IsColumnNull(Invoices.ColumnNames.CustomerID))
                    {
                        Customers cust = new Customers();
                        cust.LoadByPrimaryKey(ivc.CustomerID);
                        if (cust.RowCount > 0)
                        {
                            cust.PaidAmount -= paidAmount;
                            cust.TotalAmount -= ivc.TotalAmount;

                            cust.Save();
                        }
                    }

                    RepairJob job = RepairJob.GetJobByInvoiceID(ivc.ID);
                    if (job.RowCount > 0)
                    {
                        if (!job.IsColumnNull(RepairJob.ColumnNames.PreviousStatusID))
                            job.StatusID = job.PreviousStatusID;
                        else
                        {
                            RepairStatusHistories hist = RepairStatusHistories.GetLastestStatusAfter(job.ID, job.StatusID);
                            if (hist.RowCount > 0)
                                job.StatusID = hist.RepairStatusID;
                            else
                                job.StatusID = RepairStatus.NoStatus;
                        }

                        job.Note = RepairJob.DrawMemo(string.Format("Reverted invoice #{0}", ivc.InvoiceNo), View_Users.GetCurrentUser().s_FullName) + job.s_Note;
                        job.Save();

                        RepairStatusHistories hist1 = new RepairStatusHistories();
                        hist1.AddNew();
                        hist1.RepairJobID = job.ID;
                        hist1.BranchID = Branches.CurrentBranchID;
                        hist1.RepairStatusID = job.StatusID;
                        hist1.UpdatedByUser = View_Users.GetCurrentUser().ID;
                        hist1.UpdatedDate = DateTime.UtcNow.AddHours(SystemVariables.SysVars.TimeZone);
                        hist1.Save();
                    }

                    Contracts cnt = Contracts.GetContractByInvoiceID(ivc.ID);
                    if (cnt.RowCount > 0)
                    {
                        cnt.Deleted = true;
                        cnt.Save();
                    }

                    if (payment.RowCount > 0)
                        payment.Save();

                    if (ivcDetails.RowCount > 0)
                        ivcDetails.Save();

                    ivc.Deleted = true;
                    ivc.LastModifiedByUser = userID;
                    ivc.LastModifiedDate = DateTime.UtcNow.AddHours(SystemVariables.SysVars.TimeZone);
                    ivc.Save();

                    tx.CommitTransaction();
                }
                //....
            }
            catch (Exception ex)
            {
                tx.RollbackTransaction();
                ErrorLog.WriteToFile("Invoices.cs", "RevertInvoice", ex.StackTrace);
                throw ex;
            }
        }
    }
}
